/* MeggyJrSimple.h
 * A rather stupid siimulator of the Meggy library, so that I could
 * debug my programs on a full-powered computer, and only *then* put
 * them onto my meggy.
 */
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <SDL.h>
#include <windows.h>



/*
  MeggyJrSimple.h - Meggy Jr RGB library for Arduino
   The Meggy Jr Simplified Library (MJSL) Simulator
   
  Version 1.2 - 19/1/2009
  Copyright (c) 2009 Ken A. Corey. All right reserved.
  Version 1.0 - 11/01/2008
  Copyright (c) 2008 Windell H. Oskay.  All right reserved.
  http://www.evilmadscientist.com/

    This library is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this library.  If not, see <http://www.gnu.org/licenses/>.


    If you *must* have a tight loop, at least have the decency to allow SDL to
    track key state like this:

    while (looping) {
#ifdef MeggySimulator
    CheckSDLEvents();
    CheckButtonsDown();
#endif
      doingSomething();
    }

	  
*/

#ifndef MeggySimulator
#define MeggySimulator

#define PROGMEM

byte GameSlate[8][8];       
byte lastButtonState;

byte Button_A;		 
byte Button_B;
byte Button_Up;
byte Button_Down;
byte Button_Left;
byte Button_Right;

struct {
  SDL_Surface *screen;
  unsigned long mykeystate;
  unsigned char LEDstate;
  int eventdone;
  byte (*GetButtons)(void);
  byte (*GetPixelR)(byte x, byte y);
  byte (*GetPixelG)(byte x, byte y);
  byte (*GetPixelB)(byte x, byte y);
  void (*SetPxClr)(byte x, byte y, byte rgb[3]);
  byte SoundAllowed;
} Meg;

struct {
  void (*begin)();
  void (*print)();
  void (*println)();
} Serial;

void randomSeed(unsigned int seed);
unsigned long random(unsigned int min, unsigned int max);

unsigned long SoundStopTime;
byte  ToneInProgress;
 
#define MeggyCursorColor   255,255,255				// You can define color constants like this.
// Predefined Colors: 
#define MeggyDark      0,  0,   0
#define MeggyRed       0xff,  0,   0
#define MeggyOrange   0xff,  0x88,   0
#define MeggyYellow    0xff,  0xff,  0
#define MeggyGreen     0,  0xff,  0
#define MeggyBlue      0,   0,  0xff
#define MeggyViolet    0x80,   0,  0xff
#define MeggyWhite     0xff,  0xff,  0xff 
 
#define MeggyDimRed    0x80,  0,   0
#define MeggyDimGreen  0x80,  0x44,   0
#define MeggyDimBlue   0,  0,   0x80
#define MeggyDimOrange 0x7b, 0x33,   0 
#define MeggydimYellow 0x80,  0x80,   0
#define MeggydimAqua   0,  0,   0x80
#define MeggydimViolet 0x40,  0,   0x80

//Color lookup Table
extern byte ColorTable[26][3];

// Assign those colors names that we can use:
enum colors {
  Dark, Red, Orange, Yellow, Green, Blue, Violet, White, 
  DimRed,DimOrange,DimYellow,DimGreen,DimAqua,DimBlue,DimViolet,FullOn,
    CustomColor0, CustomColor1, CustomColor2, CustomColor3, CustomColor4,  
	CustomColor5, CustomColor6, CustomColor7, CustomColor8, CustomColor9
	};     

  // Stop the note if its completion time has come.
void Tone_Update(void);
void CheckButtonsDown();
void CheckButtonsPress();
 
// Write a byte to the Auxiliary LED set at the top of the LED matrix display.  
void SetAuxLEDs(byte InputLEDs);

// Write a byte to the Auxiliary LED set at the top of the LED matrix display.  
// This version reverses bit order, so you can call it with an explicit binary number
void SetAuxLEDsBinary(byte n);

// Simple function to color in a pixel at position (x,y,color):
void DrawPx(byte xin, byte yin, byte color);

// function to read color of pixel at position (x,y):
byte ReadPx(byte xin, byte yin);

//Empty the Game Slate:
void ClearSlate(void);

// DisplaySlate() :: Write the Game Slate to the Display Memory it.
// This function looks up each color number (name) stored in the Game Slate,
// retreives its R,G,B components from the color table, and writes them to the
// R,G,B parts of the display memory.

void DisplaySlate (void);
  

  // Pre-defined sound divisors:
 
#define ToneB2		64783 

#define ToneC3		61157	
#define ToneCs3		57724
#define ToneD3		54485	
#define ToneDs3		51427
#define ToneE3		48541	
#define ToneF3		45816	
#define ToneFs3		43243
#define ToneG3		40816	
#define ToneGs3		38526
#define ToneA3		36363
#define ToneAs3		34323
#define ToneB3		32397
 
#define ToneC4		30578
#define ToneCs4		28862
#define ToneD4		27242
#define ToneDs4		25713
#define ToneE4		24270
#define ToneF4		22908
#define ToneFs4		21622
#define ToneG4		20408
#define ToneGs4		19263
#define ToneA4		18182 
#define ToneAs4		17161
#define ToneB4		16198 

#define ToneC5		15289
#define ToneCs5		14431
#define ToneD5		13626
#define ToneDs5		12857
#define ToneE5		12135
#define ToneF5		11454
#define ToneFs5		10811
#define ToneG5		10204
#define ToneGs5		9631
#define ToneA5		9091 
#define ToneAs5		8581
#define ToneB5		8099 

#define ToneC6		7645
#define ToneCs6		7215
#define ToneD6		6810
#define ToneDs6		6428
#define ToneE6		6067
#define ToneF6		5727
#define ToneFs6		5405
#define ToneG6		5102
#define ToneGs6		4816
#define ToneA6		4545 
#define ToneAs6		4290
#define ToneB6		4050 

#define ToneC7		3822
#define ToneCs7		3608
#define ToneD7		3406
#define ToneDs7		3214
#define ToneE7		3034
#define ToneF7		2863
#define ToneFs7		2703
#define ToneG7		2551
#define ToneGs7		2408
#define ToneA7		2273 
#define ToneAs7		2145
#define ToneB7		2025 

#define ToneC8		1911
#define ToneCs8		1804
#define ToneD8		1703
#define ToneDs8		1607
#define ToneE8		1517
#define ToneF8		1432
#define ToneFs8		1351
#define ToneG8		1276
#define ToneGs8		1204
#define ToneA8		1136 
#define ToneAs8		1073
#define ToneB8		1012 

#define ToneC9		956
#define ToneCs9		902
#define ToneD9		851
#define ToneDs9		803

  /*
 Sound output:
 
 Frequency is given by the following formula:
 
 f= 8 MHz/divisor, so divisor = 8 MHz/f.   (Round to nearest.)
 Maximum divisor: 65535, so min. frequency is 122 Hz
 
 Example: for 440 Hz, divisor = 18182
  
 */
  
   // "Cheater" functions
 #define SoundOn()    Meg.SoundState(1)
 #define SoundOff()   Meg.SoundState(0)
 #define MakingSound  Meg.ToneInProgress
 
 // other sound functions:
void Tone_Start(unsigned int divisor, unsigned int duration_ms);
void EditColor(byte WhichColor, byte RedComponent, byte GreenComponent, byte BlueComponent);
void MeggyJrSimpleSetup(void); 

 // misc support functions:  
unsigned long millis();
void delay(unsigned long delaymilis);
extern void setup();
extern void loop();
void CheckSDLEvents();
  
// These are MeggyJr calls I've needed to emulate...
byte GetPixelR(byte x, byte y);
byte GetPixelG(byte x, byte y);
byte GetPixelB(byte x, byte y);

void SetPxClr(byte x, byte y, byte rgb[3]);

#define 	PROGMEM
#define 	PSTR(s) s
#define 	pgm_read_byte_near(address_short) (*address_short)
#define 	pgm_read_word_near(address_short) (*address_short)
#define 	pgm_read_dword_near(address_short) (*address_short)
#define 	pgm_read_float_near(address_short) (*address_short)
#define 	pgm_read_byte_far(address_long) (*address_long)
#define 	pgm_read_word_far(address_long) (*address_long)
#define 	pgm_read_dword_far(address_long) (*address_long)
#define 	pgm_read_float_far(address_long) (*address_long)
#define 	pgm_read_byte(address_short) (*address_short)
#define 	pgm_read_word(address_short) (*address_short)
#define 	pgm_read_dword(address_short) (*address_short)
#define 	pgm_read_float(address_short) (*address_short)
#define 	PGM_P   const prog_char *
#define 	PGM_VOID_P   const prog_void *

typedef void PROGMEM 	prog_void;
typedef char PROGMEM 	prog_char;
typedef unsigned char PROGMEM 	prog_uchar;
typedef int8_t PROGMEM 	prog_int8_t;
typedef uint8_t PROGMEM 	prog_uint8_t;
typedef int16_t PROGMEM 	prog_int16_t;
typedef uint16_t PROGMEM 	prog_uint16_t;
typedef int32_t PROGMEM 	prog_int32_t;
typedef uint32_t PROGMEM 	prog_uint32_t;
typedef int64_t PROGMEM 	prog_int64_t;
typedef uint64_t PROGMEM 	prog_uint64_t;

 #endif
